package cn.darkhorse.ticket.store.service.impl;

import cn.darkhorse.exception.ServiceException;
import cn.darkhorse.ticket.basis.dao.TicketProductDao;
import cn.darkhorse.ticket.code.RepeatCheck;
import cn.darkhorse.ticket.constants.TicketConstants;
import cn.darkhorse.ticket.store.dao.TicketWarehousingDao;
import cn.darkhorse.ticket.store.dto.TicketWarehousing2DTO;
import cn.darkhorse.ticket.store.dto.TicketWarehousingDTO;
import cn.darkhorse.ticket.store.dto.TicketProductDetailsDTO;
import cn.darkhorse.ticket.store.mapper.TicketWarehousingMapper;
import cn.darkhorse.ticket.store.pojo.TicketWarehousing;
import cn.darkhorse.ticket.store.pojo.TicketWarehousingSub;
import cn.darkhorse.ticket.store.service.TicketInventoryService;
import cn.darkhorse.ticket.store.service.TicketWarehousingService;
import cn.darkhorse.ticket.store.service.TicketWarehousingSubService;
import cn.darkhorse.ticket.store.service.verification.ICalculationService.IQuantityRecordService;
import cn.darkhorse.ticket.store.service.verification.impl.BasePurchaseSurplus;
import cn.darkhorse.ticket.store.vo.TicketWarehousingVO;
import cn.darkhorse.ticket.store.vo.TicketWarehousingViewVO;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.mapper.SysUserMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 入库主表 服务实现类
 * </p>
 *
 * @author wangxinghui
 * @since 2024-01-16
 */
@Service
public class TicketWarehousingServiceImpl extends ServiceImpl<TicketWarehousingMapper, TicketWarehousing> implements TicketWarehousingService {
	
	@Resource
	private SysUserMapper userMapper;
	@Resource
	private RepeatCheck<TicketWarehousingDTO> repeatCheck;
	@Resource
	private TicketWarehousingSubService warehousingSubService;
	@Resource
	private TicketProductDao productDao;
	@Resource
	private TicketInventoryService inventoryService;
	@Resource
	private BasePurchaseSurplus purchaseSurplus;
	@Resource(name = "increaseService")
	private IQuantityRecordService increaseService;
	@Resource
	private TicketWarehousingDao warehousingDao;
	
	/**
	 * 列表
	 * @param code
	 * @param name
	 * @param beginTime
	 * @param endTime
	 * @return
	 */
	@Override
	public List<TicketWarehousingVO> list(String code, String name, String beginTime, String endTime) {
		Map<String,Object> params = new HashMap<>();
		params.put("code",code);
		params.put("name",name);
		params.put("beginTime",beginTime);
		params.put("endTime",endTime);
		List<TicketWarehousingVO> list = warehousingDao.list(params);
		return list;
	}
	
	@Transactional(rollbackFor = Exception.class)
	@Override
	public String add( TicketWarehousingDTO warehousingDTO) {
		//重复校验
		String s = repeatCheck.repeatCode(this, warehousingDTO, TicketConstants.BUSINESS_TYPE_IN);
		if(StringUtils.isNotBlank(s)){
			warehousingDTO.setCode(s);
		}
		List<TicketProductDetailsDTO> productDetailsDTOList = getWarehousingSub(warehousingDTO.getDetails());
		//无需校验
		//保存
		save(warehousingDTO);
		//明细
		List<TicketWarehousingSub> subList = new ArrayList<>();
		productDetailsDTOList.forEach(item->{
			item.setBusinessId(warehousingDTO.getId());
			TicketWarehousingSub sub = new TicketWarehousingSub();
			BeanUtil.copyProperties(item,sub);
			sub.setWarehousingId(warehousingDTO.getId());
			subList.add(sub);
		});
		warehousingSubService.saveBatch(subList);
/*		//修改库存
		inventoryService.add(warehousingSubs);*/
		//记录数量变化
		increaseService.changeQuantity(productDetailsDTOList);
		return s;
	}
	
	
	
	/**
	 * 修改
	 * @param warehousingDTO
	 */
	@Transactional(rollbackFor = Exception.class)
	@Override
	public void modify(TicketWarehousing2DTO warehousingDTO) {
		TicketWarehousingDTO dto = new TicketWarehousingDTO();
		dto.setId(warehousingDTO.getId());dto.setName(warehousingDTO.getName());
		//不需要重复校验

		//校验数量问题
		List<TicketWarehousingSub> details = warehousingDTO.getDetails();
		List<TicketProductDetailsDTO> productDetails = getProductDetails(getDetails(warehousingDTO.getId()));
		productDetails.forEach(item->{
			item.setBusinessType("ROLLBACK");
			item.setQuantity(item.getQuantity().negate());
		});
		increaseService.changeQuantity(productDetails);
		purchaseSurplus.setProductDetailsDTOList(getProductDetails(details));
		purchaseSurplus.check();
		//保存
		updateById(warehousingDTO);
		//明细
		warehousingSubService.updateBatchById(details);
		//记录数量变化
		increaseService.changeQuantity(getProductDetails(details));
	}
	
	/**
	 * 查看
	 * @param id
	 * @return
	 */
	@Override
	public TicketWarehousingViewVO view(Long id) {
		TicketWarehousingViewVO vo = new TicketWarehousingViewVO();
		TicketWarehousing warehousing = getById(id);
		if(Objects.isNull(warehousing)){
			throw new ServiceException("单据不存在！");
		}
		List<SysUser> sysUsers = userMapper.selectUserListNoAuth(new SysUser());
		Map<Long, SysUser> sysUserMap=sysUsers.stream().collect(Collectors.toMap(SysUser::getUserId, Function.identity()));
		BeanUtil.copyProperties(warehousing,vo);
		vo.setDetails(getDetails(id));
		vo.setFounderName(sysUserMap.get(warehousing.getFounder()).getNickName());
		vo.setReviserName(Objects.isNull(warehousing.getReviser())?null:sysUserMap.get(warehousing.getReviser()).getNickName());
		return vo;
	}
	
	/**
	 * 删除
	 * @param id
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class)
	@Override
	public boolean delete(Long id) {
		//校验能否删除
		List<TicketProductDetailsDTO> productDetails = getProductDetails(getDetails(id));
		productDetails.forEach(item->{
			item.setQuantity(item.getQuantity().negate());
			item.setBusinessType("DELETE");
		});
		purchaseSurplus.setProductDetailsDTOList(productDetails);
		purchaseSurplus.check();
		boolean b = removeById(id);
		if(b){
			warehousingSubService.remove(new LambdaQueryWrapper<TicketWarehousingSub>()
					.eq(TicketWarehousingSub::getWarehousingId,id));
		}
		//记录日志
		increaseService.changeQuantity(productDetails);
		return false;
	}
	
	@Override
	public void isCanBe(Long id) {
		List<TicketProductDetailsDTO> productDetails = getProductDetails(getDetails(id));
		productDetails.forEach(item->{
			item.setQuantity(item.getQuantity().negate());
		});
		purchaseSurplus.setProductDetailsDTOList(productDetails);
		purchaseSurplus.check();
	}
	
	/**
	 * 明细
	 * @param warehousingId
	 * @return
	 */
	private List<TicketWarehousingSub> getDetails(Long warehousingId){
		LambdaQueryWrapper<TicketWarehousingSub> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(TicketWarehousingSub::getWarehousingId, warehousingId);
		return warehousingSubService.list(queryWrapper);
	}
	
	
	/**
	 * 产品信息转化为入库产品信息
	 * @param details
	 * @return
	 */
	private List<TicketProductDetailsDTO> getWarehousingSub(List<TicketWarehousingDTO.WsDetailsDTO> details){
		List<TicketProductDetailsDTO> subDTOS = new ArrayList<>();
		if(null == details || details.isEmpty()){
			return subDTOS;
		}
		List<Long> ids = new ArrayList<>();
		details.forEach(item->{
			ids.add(item.getProductId());
		});
		List<cn.darkhorse.ticket.basis.dto.TicketProductDetailsDTO> detailsDTOList = productDao.getDetails(ids);
		Map<Long, cn.darkhorse.ticket.basis.dto.TicketProductDetailsDTO> dtoMap = detailsDTOList.stream().collect(Collectors.toMap(cn.darkhorse.ticket.basis.dto.TicketProductDetailsDTO::getProductId, Function.identity()));
		details.forEach(item->{
			TicketProductDetailsDTO subDTO = new TicketProductDetailsDTO();
			BeanUtil.copyProperties(item,subDTO,new String[]{"id"});
			cn.darkhorse.ticket.basis.dto.TicketProductDetailsDTO ticketProductDetailsDTO = dtoMap.get(item.getProductId());
			BeanUtil.copyProperties(ticketProductDetailsDTO,subDTO);
			subDTOS.add(subDTO);
		});
		return subDTOS;
	}
	
	
	/**
	 * 将修改明细转化为产品实体
	 * @param details
	 * @return
	 */
	private List<TicketProductDetailsDTO> getProductDetails(List<TicketWarehousingSub> details){
		List<TicketProductDetailsDTO> productDetailsDTOList = new ArrayList<>();
		details.forEach(item->{
			//修改不能增加新产品，如果允许增加新的产品信息，此处需取到产品分类
			TicketProductDetailsDTO detailsDTO = new TicketProductDetailsDTO();
			BeanUtil.copyProperties(item,detailsDTO);
			detailsDTO.setBusinessId(item.getWarehousingId());
			productDetailsDTOList.add(detailsDTO);
		});
		return productDetailsDTOList;
	}
	
	
	
	
}
